home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / Xpm / pixmap / PortEditorP.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  20KB  |  752 lines

  1. /*
  2.  * $Id: PortEditorP.c,v 1.2 1992/10/27 08:41:56 mallet Exp $
  3.  *
  4.  * Copyright 1992 Lionel Mallet
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appears in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of Lionel MALLET not be used in
  11.  * advertising or publicity pertaining to distribution of the software
  12.  * without specific, written prior permission.  Lionel MALLET makes no
  13.  * representations about the suitability of this software for any
  14.  * purpose.  It is provided "as is" without express or implied warranty.
  15.  *
  16.  * Lionel MALLET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  17.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  18.  * FITNESS, IN NO EVENT SHALL Lionel MALLET BE LIABLE FOR ANY SPECIAL,
  19.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  20.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  21.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  22.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  23.  *
  24.  *  This software is opened and free. Furthermore, everybody is kindly
  25.  * invited to participate to improve it for the benefit of all.
  26.  * Improvements can be new features, bugs fixes and porting issues
  27.  * resolution.
  28.  *
  29.  * Author:  Tim Wise - Scientific & Engineering Software (SES), Inc.
  30.  */
  31.  
  32. #include <string.h>
  33.  
  34. /*****************************************************************************/
  35. /*
  36.             Port List Routines 
  37.  
  38.     A list of ports is kept in the XpmExtension format which is an
  39.     array of strings, one for each port. Convert string format
  40.     to Port structure when needed.
  41. */
  42. /*****************************************************************************/
  43.  
  44. Boolean _PORTDEBUG = True;
  45.  
  46. #define XpmPortName    "Ports"
  47. #define UNKNOWN        -1
  48.  
  49. typedef char PortInfo[80];
  50.  
  51. typedef struct {
  52.     int  id;        /* unique number */
  53.     int  x;        /* location of port */
  54.     int  y;
  55.     char info[80];     /* port info: name, kind */
  56. } Port;
  57.  
  58.  
  59. /*--------------------------------------------------------------------------*/
  60. /*
  61.             N e w P o r t 
  62.  
  63.     Allocate a new port structure including a string for info.
  64.     Return a pointer to allocated structure.
  65. */
  66. /*--------------------------------------------------------------------------*/
  67. Port *NewPort()
  68. {
  69.     Port *p;
  70.  
  71.     p = (Port *) XtNew(Port);
  72.     if (p != NULL) {
  73.         p->id = UNKNOWN;
  74.         p->x  = UNKNOWN;
  75.         p->y  = UNKNOWN;
  76.         /* p->info = XtMalloc( sizeof(PortInfo) ) */
  77.         p->info[0] = '\0';
  78.     }
  79.     return  p;
  80. }
  81.  
  82.  
  83. /*--------------------------------------------------------------------------*/
  84. /*
  85.             S t r T o P o r t
  86.  
  87.     Convert a string to a port structure. Return a pointer to the
  88.      port structure. NOTE: Caller must free structure!!
  89. */
  90. /*--------------------------------------------------------------------------*/
  91. void StrToPort( str, p )
  92.     char *str;
  93.     Port *p;
  94. {
  95.     char *s, *t;
  96.  
  97.     if (str != NULL && p != NULL) {
  98.  
  99.         sscanf( str, "%d%d%d",&p->id, &p->x, &p->y );
  100.         p->info[0] = '\0';
  101.  
  102.     s = XtMalloc( strlen(str) + 1 );    
  103.         strcpy( s, str );
  104.         t = strtok( s, " ," );         /* first token  id */
  105.         t = strtok( NULL, " ," );    /* second token x  */
  106.         t = strtok( NULL, " ," );    /* third token  y  */
  107.  
  108.         if (t != NULL && t+strlen(t)+1 < s+strlen(str)) 
  109.             strcpy( p->info, t+strlen(t)+1 );/* stuff after tokens */
  110.         
  111.     }
  112. }
  113.  
  114.  
  115. /*--------------------------------------------------------------------------*/
  116. /*
  117.             P o r t T o S t r
  118.  
  119.     Convert a port structure to a string. Return pointer to string.
  120.     Caller must free string.
  121. */
  122. /*--------------------------------------------------------------------------*/
  123. char *PortToStr( p )
  124.     Port *p;
  125. {
  126.     char id_str[40];
  127.     char x_str[40];
  128.     char y_str[40];
  129.     char *str = NULL;
  130.  
  131.     if (p != NULL) {
  132.         sprintf( id_str, "%d\0", p->id );
  133.         sprintf( x_str,  "%d\0", p->x );
  134.         sprintf( y_str,  "%d\0", p->y );
  135.     str = XtMalloc( strlen(x_str) + strlen(y_str) + strlen(id_str)
  136.                         + strlen(p->info) + 4 );
  137.         str[0] = '\0';
  138.         strcat( str, id_str  );
  139.         strcat( str, " "     );
  140.         strcat( str, x_str   );
  141.         strcat( str, " "     );
  142.         strcat( str, y_str   );
  143.         strcat( str, " "     );
  144.         strcat( str, p->info );
  145.     }
  146.     return str;
  147. }
  148.  
  149.  
  150. /*--------------------------------------------------------------------------*/
  151. /*
  152.             U p d a t e P o r t 
  153.  
  154.     Replace string version of port i with info given in port structure.
  155. */
  156. /*--------------------------------------------------------------------------*/
  157. void UpdatePort( ports, i, p )
  158.     XpmExtension *ports;
  159.     int          i;
  160.     Port         *p;
  161. {
  162.     XtFree( ports->lines[i] );
  163.     ports->lines[i] = PortToStr( p );
  164. }
  165.  
  166.  
  167. /*--------------------------------------------------------------------------*/
  168. /*
  169.             F i n d P o r t 
  170.  
  171.     Search a list of ports and find the first at location (x,y).
  172.     If found, return index of port; otherwise return UNKNOWN.
  173. */
  174. /*--------------------------------------------------------------------------*/
  175. int FindPort( ports, at_x, at_y )
  176.     XpmExtension *ports;
  177.     Position     at_x;
  178.     Position     at_y;
  179. {
  180.     int   i;
  181.     int   x;
  182.     int   y;
  183.     Port  p;
  184.  
  185.     if (strcmp(ports->name, XpmPortName) == 0) {
  186.         for (i=0; i < ports->nlines ; i++) {
  187.             if ( StrToPort(ports->lines[i], &p) 
  188.                  && p.x == at_x && p.y == at_y ) {
  189.                 return i;
  190.             }
  191.         }
  192.     }
  193.     return UNKNOWN;
  194. }
  195.  
  196.  
  197. /*--------------------------------------------------------------------------*/
  198. /*
  199.              I s P o r t 
  200.  
  201.     See if a port exists at location (x,y). If so, return True and
  202.     set the index of the port extension and the index of the port. 
  203. */
  204. /*--------------------------------------------------------------------------*/
  205.  
  206. Boolean IsPort( w, x, y, ports, port_i )
  207.     widget       w;
  208.     Position     x;
  209.     Position     y;
  210.     XpmExtension **return_ports;    /* list of ports; can be NULL! */
  211.     int          *return_port_i;    /* index of port x,y; can be NULL! */
  212.  
  213. {
  214.     Boolean      result = False;
  215.     XpmExtension *ports;
  216.     int         i;
  217.     
  218.     if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) { 
  219.        if ( (j=FindPort(ports, x, y)) >= 0 ) {
  220.            result = True;
  221.        }
  222.     }
  223.     if ( return_port_i != NULL )
  224.         *return_port_i = port_i;
  225.  
  226.     if ( return_ports != NULL ) 
  227.         *return_ports = ports;
  228.  
  229.     else if ( ports != NULL )
  230.         XpmFreeExtension( ports );    /* free ports if caller */
  231.                                         /* doesn't want them    */
  232.     return result;
  233. }
  234.  
  235.  
  236. /*--------------------------------------------------------------------------*/
  237. /*
  238.             A d d P o r t
  239.  
  240.     Add a port to end of list. Return index of new port.
  241. */
  242. /*--------------------------------------------------------------------------*/
  243. int AddPort( ports, at_x, at_y )
  244.     XpmExtension *ports;
  245.     Position     at_x;
  246.     Position     at_y;
  247. {
  248.     Port *p;
  249.     char *port_str;
  250.     int  i = UNKNOWN;
  251.  
  252.     if ((p=NewPort()) != NULL) {
  253.  
  254.         p->x  = at_x;
  255.         p->y  = at_y;
  256.         p->id = 0;        /* mark as new port */
  257.  
  258.         if ( (port_str=PortToStr(p)) != NULL ) {
  259.  
  260.            i = ports->nlines;
  261.            ports->nlines++;
  262.  
  263.            if (ports->lines != NULL)
  264.                ports->lines = (char **) XtRealloc( 
  265.                                            ports->lines, 
  266.                                            ports->nlines * sizeof(char*) );
  267.            else 
  268.                ports->lines = (char **) XtNew( char** );
  269.  
  270.            ports->lines[i] = port_str;
  271.         }
  272.         XtFree(p);
  273.     }
  274.     return i;
  275.  
  276.  
  277.  
  278. /*--------------------------------------------------------------------------*/
  279. /*
  280.             D e l P o r t
  281.  
  282.     Delete port i. Shift array elements above i to the left.
  283. */
  284. /*--------------------------------------------------------------------------*/
  285. void DelPort( ports, i )
  286.     XpmExtension *ports;
  287.     int          i;
  288. {
  289.     char **s, **t, **last;
  290.  
  291.     XtFree( ports->lines[i] );
  292.  
  293.     last = ports->lines + ports->nlines;    /* last element */
  294.     ports->nlines--;
  295.  
  296.     /* shift left elements above deletion, if necessary */
  297.     if (ports->nlines > 0) 
  298.         for (t = ports->lines+i, s = ports->lines+i+1 ; s < last ; *t++ = *s++);
  299.     else {
  300.         XtFree( ports->lines );
  301.         ports->lines = NULL;
  302.     }
  303.  
  304.  
  305. /*--------------------------------------------------------------------------*/
  306. /*
  307.             T r a n s l a t e P o r t
  308.  
  309.     Add offsets dx and dy to location of port i.
  310. */
  311. /*--------------------------------------------------------------------------*/
  312. void TranslatePort( ports, port_i, dx, dy )
  313.     XpmExtension *ports;
  314.     int port_i;
  315.     int dx;
  316.     int dy;
  317. {
  318.     Port p;
  319.  
  320.     if ( StrToPort(ports->lines[port_i], &p) ) {
  321.         p.x += dx;
  322.         p.y += dy;
  323.         UpdatePort( ports, port_i, &p );
  324.     }
  325. }
  326.  
  327.  
  328. /*****************************************************************************/
  329. /*
  330.             Graphics Routines to draw  ports
  331. */
  332. /*****************************************************************************/
  333.  
  334.  
  335. /*--------------------------------------------------------------------------*/
  336. /*
  337.             P o r t S h a p e
  338.  
  339.     Return an array of points defining a port's shape.
  340. */
  341. /*--------------------------------------------------------------------------*/
  342. XPoint *PortShape(PW, x ,y)
  343.     PixmapWidget PW;
  344.     Position     x; 
  345.     Position     y;
  346. {
  347. #define NPortPoints 7
  348.     static XPoint points[NPortPoints];
  349.  
  350.     points[0].x = InWindowX(PW, x);
  351.     points[0].y = InWindowY(PW, y);
  352.     points[1].x = InWindowX(PW, x + 1.0/2);
  353.     points[1].y = InWindowY(PW, y + 1.0/2);
  354.     points[2].x = InWindowX(PW, x);
  355.     points[2].y = InWindowY(PW, y + 1);
  356.     points[3].x = InWindowX(PW, x + 1);
  357.     points[3].y = InWindowY(PW, y + 1);
  358.     points[4].x = InWindowX(PW, x + 1.0/2);
  359.     points[4].y = InWindowY(PW, y + 1.0/2);
  360.     points[5].x = InWindowX(PW, x + 1);
  361.     points[5].y = InWindowY(PW, y);
  362.     points[6].x = InWindowX(PW, x);
  363.     points[6].y = InWindowY(PW, y);
  364.  
  365.     return points;
  366. }
  367.  
  368.  
  369. /*--------------------------------------------------------------------------*/
  370. /*
  371.             D r a w P o r t
  372. */
  373. /*--------------------------------------------------------------------------*/
  374. #define DrawPort(w, x, y) \
  375.   XFillPolygon(XtDisplay(w), XtWindow(w), PW->pixmap.framing_gc,\
  376.                PortShape(w, x, y), NPortPoints, Convex, CoordModeOrigin)
  377.  
  378.  
  379. /*--------------------------------------------------------------------------*/
  380. /*
  381.             H i g h l i g h t P o r t
  382. */
  383. /*--------------------------------------------------------------------------*/
  384. #define HighlightPort(w, x, y)\
  385.   XFillPolygon(XtDisplay(w), XtWindow(w), PW->pixmap.highlighting_gc,\
  386.                PortShape(w, x, y), NPortPoints, Convex, CoordModeOrigin)
  387.  
  388.  
  389.  
  390. /*****************************************************************************/
  391. /*
  392.         Port Editor Interface Routines 
  393. */
  394. /*****************************************************************************/
  395.  
  396.  
  397. /*--------------------------------------------------------------------------*/
  398. /*
  399.             D r a w P o r t 
  400.  
  401.     Just draw a port a location (x,y) with given value (set, clear, 
  402.     invert, or highlight). 
  403. */
  404. /*--------------------------------------------------------------------------*/
  405. void DrawPort( w, x, y, value )
  406.     Widget   w;
  407.     Position x;
  408.     Position y;
  409.     int      value;
  410. {
  411.     if (value == Set)
  412.         DrawPort( w, x, y );
  413.  
  414.     else if (value == Clear || value == Invert)
  415.         DrawPort( w, x, y );
  416.  
  417.     else if (value == Highlight)
  418.         HighlightPort( w, x, y );
  419. }
  420.  
  421.  
  422. /*--------------------------------------------------------------------------*/
  423. /*
  424.             D r a w I f P o r t 
  425.  
  426.     Draw a port at location (x,y) if there is a port at that 
  427.     location. This routine is used to highlight a port that a
  428.     user is trying to pick.
  429. */
  430. /*--------------------------------------------------------------------------*/
  431. void DrawIfPort( w, x, y, value )
  432.     Widget   w;
  433.     Position x;
  434.     Position y;
  435.     int      value;
  436. {
  437.     if ( IsPort(w, x, y, NULL, NULL) )
  438.         DrawPort( w, x, y, value );
  439.  
  440.  
  441. /*--------------------------------------------------------------------------*/
  442. /*
  443.             S e t P o r t 
  444.  
  445.     Create and draw a port at (x,y) if there is not already a port
  446.     there. 
  447. */
  448. /*--------------------------------------------------------------------------*/
  449. void SetPort( w, x, y, value )
  450.     Widget   w;
  451.     Position x;
  452.     Position y;
  453.     int      value;
  454. {
  455.     int ext_i, port_i;
  456.  
  457.     if (_PORTDEBUG)
  458.         printf("SetPort : %d %d \n", x, y);
  459.  
  460.     if ( !IsPort(w, x, y, &ext_i, &port_i) ) {
  461.         if (ext_i == UNKNOWN) 
  462.             ext_i = AddExtension( &(PW->pixmap.extensions), 
  463.                                   &(PW->pixmap.nextensions), XpmPortName );
  464.  
  465.         AddPort(PW->pixmap.extensions + ext_i, x, y);
  466.         DrawPort(w, x, y, value);
  467.  
  468.     if (_PORTDEBUG)
  469.             PrintExtensions(PW->pixmap.extensions, PW->pixmap.nextensions);
  470.     }
  471.  
  472.  
  473. /*--------------------------------------------------------------------------*/
  474. /*
  475.             C l e a r P o r t 
  476.  
  477.     Delete the port at (x,y) from the port list and erase the port 
  478.     on the screen.
  479. */
  480. /*--------------------------------------------------------------------------*/
  481. void ClearPort(w, x, y, value)
  482.     Widget   w;
  483.     Position x;
  484.     Position y;
  485.     int      value;
  486. {
  487.     int ext_i, port_i;
  488.  
  489.     PixmapWidget PW = (PixmapWidget) w;
  490.  
  491.     if (_PORTDEBUG)
  492.         printf("PWClearPort : %d %d \n", x, y);
  493.  
  494.     if ( IsPort(PW, x, y, &ext_i, &port_i) ) { 
  495.         DelPort(PW->pixmap.extensions + ext_i, port_i);
  496.  
  497.         /* if no more data for this extension, delete it */
  498.         if (PW->pixmap.extensions[ext_i].nlines == 0)
  499.             DelExtension( &(PW->pixmap.extensions),
  500.                           &(PW->pixmap.nextensions), ext_i );
  501.  
  502.         DrawPort(w, x, y, value);
  503.     if (_PORTDEBUG)
  504.             PrintExtensions(PW->pixmap.extensions, PW->pixmap.nextensions);
  505.     }
  506. }
  507.  
  508.  
  509. /*--------------------------------------------------------------------------*/
  510. /*
  511.             D r a g P o r t 
  512.  
  513.     Draw a port while the user is dragging. Draw only if a port existed
  514.     at the starting location of the drag. 
  515. */
  516. /*--------------------------------------------------------------------------*/
  517.  
  518. static struct {
  519.     Boolean b;        /* Are we dragging? */
  520.     XPoint  from;    /* starting point of drag */
  521. } dragging = { False };
  522.  
  523. void DragPort(w, x, y, value)
  524.     Widget   w;
  525.     Position x;
  526.     Position y;
  527.     int      value;
  528. {
  529.     PixmapWidget PW = (PixmapWidget) w;
  530.  
  531.     /* if beginning of drag, ... */
  532.     if (dragging.b == False) {
  533.         dragging.b = True;
  534.     dragging.from.x = x;
  535.     dragging.from.y = y;
  536.     }
  537.  
  538.     if (IsPort(PW, dragging.from.x, dragging.from.y, NULL, NULL)) {
  539.         DrawPort( w, dragging.from.x, dragging.from.y, value );/* erase */
  540.         DrawPort( w, x, y, value );/* draw */
  541.     }
  542. }
  543.  
  544. /*--------------------------------------------------------------------------*/
  545. /*
  546.             M o v e P o r t 
  547.  
  548.     Move a port from one location to another after user has completed
  549.     dragging.
  550. */
  551. /*--------------------------------------------------------------------------*/
  552. void MovePort( w, new_x, new_y, value )
  553.     Widget   w;
  554.     Position new_x;
  555.     Position new_y;
  556.     int      value;
  557. {
  558.     XpmExtension *ports;
  559.     Port         p;
  560.     int          i;
  561.  
  562.     if ( IsPort(w, dragging.from.x, dragging.from.y, &ports, &i) && 
  563.         !IsPort(PW, new_x, new_y, NULL, NULL)  ) {
  564.  
  565.         DrawPort( w, dragging.from.x, dragging.from.y, value );/* erase old */
  566.         DrawPort( w, new_x, new_y, value );                     /* draw  new */
  567.  
  568.         TranslatePort( ports, i, 
  569.                        new_x - dragging.from.x, 
  570.                        new_y - dragging.from.y  );
  571.  
  572.         PWUpdateExtension( w, ports );
  573.     XpmFreeExtensions( ports );
  574.     if (_PORTDEBUG)
  575.             PrintPorts( ports );
  576.     }
  577.     dragging.b = False;
  578. }
  579.  
  580.  
  581. /*--------------------------------------------------------------------------*/
  582. /*
  583.             P o r t I n f o
  584.  
  585.     Allow the user to edit the port information for the port at (x,y).
  586. */
  587. /*--------------------------------------------------------------------------*/
  588.  
  589. #include "Dialog.h"
  590. extern Dialog input_dialog;
  591.  
  592. void PortInfo( w, x, y, value )
  593.     Widget   w;
  594.     Position x;
  595.     Position y;
  596.     int      value;
  597. {
  598.     XpmExtension *ports;
  599.     Port         p;
  600.     int          i;
  601.     char         *newInfo;
  602.  
  603.     if ( IsPort(w, x, y, &ports, &i) ) { 
  604.         StrToPort( ports->lines[i], &p );
  605.         if ( PopupDialog( input_dialog, 
  606.                           "Port Info: <name> <kind>",
  607.                            p.info, &newInfo,
  608.                           XtGrabExclusive) == Okay ) {
  609.         strcpy( p.info, newInfo );
  610.             UpdatePort( ports, i, &p ); 
  611.         }
  612.         PWUpdateExtension( w, ports );
  613.     XpmFreeExtensions( ports );
  614.     if (_PORTDEBUG)
  615.             PrintPorts( ports );
  616.     }
  617. }
  618.  
  619.  
  620. /*--------------------------------------------------------------------------*/
  621. /*
  622.             R e d r a w P o r t s
  623.  
  624.     Redraw all ports of PixmapWidget.
  625. */
  626. /*--------------------------------------------------------------------------*/
  627.  
  628. void RedrawPorts( w )
  629.     Widget w;
  630. {
  631.     XpmExtension *ports;
  632.     Port         p;
  633.     int          i;
  634.  
  635.     if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) { 
  636.         for ( i=0; i < ports->nlines; i++ ) { 
  637.             StrToPort( ports->lines[i], &p );
  638.             DrawPort( w, p.x, p.y ); 
  639.         }
  640.     }
  641. }
  642.  
  643.  
  644. /*--------------------------------------------------------------------------*/
  645. /*
  646.             T r a n s l a t e P o r t s 
  647.  
  648.     For all ports in PixmapWidget, add dx,dy to the ports location.
  649. */
  650. /*--------------------------------------------------------------------------*/
  651.  
  652. void TranslatePorts( PW, dx, dy )
  653.     PixmapWidget PW;
  654.     int dx;
  655.     int dy;
  656. {
  657.     XpmExtension *ports;
  658.     Port         p;
  659.     int          i;
  660.  
  661.     if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) { 
  662.         for ( i=0; i < ports->nlines; i++ ) { 
  663.             StrToPort( ports->lines[i], &p );
  664.  
  665.             DrawPort( w, p.x, p.y );            /* erase old */
  666.             PWTranslatePoint( w, &p.x, &p.y, dx, dy ); 
  667.             DrawPort( w, p.x, p.y );            /* draw new */
  668.  
  669.         UpdatePort( ports, i, &p );
  670.         }
  671.         PWUpdateExtension( w, ports );
  672.     XpmFreeExtensions( ports );
  673.     if (_PORTDEBUG)
  674.             PrintPorts( ports );
  675.     }
  676.  
  677. }
  678.  
  679.  
  680. /*--------------------------------------------------------------------------*/
  681. /*
  682.             F l i p P o r t s 
  683.  
  684.     Flip all ports of a PixmapWidget either horiziontally or vertically.
  685. */
  686. /*--------------------------------------------------------------------------*/
  687.  
  688. void FlipPorts( w, axis  )
  689.     widget         w;
  690.     enum FlipAxis    axis;
  691. {
  692.     XpmExtension *ports;
  693.     Port         p;
  694.     int          i;
  695.  
  696.     if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) { 
  697.         for ( i=0; i < ports->nlines; i++ ) { 
  698.             StrToPort( ports->lines[i], &p );
  699.  
  700.             DrawPort( w, p.x, p.y );            /* erase old */
  701.             PWFlipPoint( w, &p.x, &p.y, axis ); 
  702.             DrawPort( w, p.x, p.y );            /* draw new */
  703.  
  704.         UpdatePort( ports, i, &p );
  705.         }
  706.         PWUpdateExtension( w, ports );
  707.     XpmFreeExtensions( ports );
  708.     if (_PORTDEBUG)
  709.             PrintPorts( ports );
  710.     }
  711. }
  712.  
  713.  
  714. /*--------------------------------------------------------------------------*/
  715. /*
  716.             R o t a t e P o r t s 
  717.  
  718.     Flip all ports of a PixmapWidget either left or right 90 degrees.
  719. */
  720. /*--------------------------------------------------------------------------*/
  721.  
  722. void RotatePorts( w, direction )
  723.     widget            w;
  724.     enum RotateDirection    direction;
  725. {
  726.     XpmExtension *ports;
  727.     Port         p;
  728.     int          i;
  729.  
  730.     if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) { 
  731.         for ( i=0; i < ports->nlines; i++ ) { 
  732.             StrToPort( ports->lines[i], &p );
  733.  
  734.             DrawPort( w, p.x, p.y );            /* erase old */
  735.             PWRotatePoint( w, &p.x, &p.y, direction ); 
  736.             DrawPort( w, p.x, p.y );            /* draw new */
  737.  
  738.         UpdatePort( ports, i, &p );
  739.         }
  740.         PWUpdateExtension( w, ports );
  741.     XpmFreeExtensions( ports );
  742.     if (_PORTDEBUG)
  743.             PrintPorts( ports );
  744.     }
  745. }
  746.  
  747.  
  748.